﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using QX.Game.PathFinder;
using System.Windows.Media.Animation;
using System.Windows.Threading;

namespace WPFGame.Windows
{
    /// <summary>
    /// UserControl8.xaml 的交互逻辑
    /// </summary>
    public partial class UserControl8 : UserControl
    {
        Rectangle rect;
        private IPathFinder PathFinder = null;
        List<PathFinderNode> path;
        private byte[,] Matrix = new byte[1024, 1024]; //寻路用二维矩阵
        private int GridSize = 20; //单位格子大小
        private System.Drawing.Point Start = System.Drawing.Point.Empty; //移动起点坐标
        private System.Drawing.Point End = System.Drawing.Point.Empty; //移动终点坐标
        DispatcherTimer timer;
        Storyboard storyboard;
        int count = 1;

        public UserControl8()
        {
            InitializeComponent();
            InitPlayer();
            InitMatrix();

            timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(100) };
            timer.Tick += new EventHandler(timer_Tick);
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e)
        {
            if (storyboard != null && path != null && storyboard.GetCurrentTime() == TimeSpan.FromMilliseconds(100 * path.Count))//如果动画完成
            {
                timer.Stop();
                spirit.Source = new BitmapImage(new Uri(Environment.CurrentDirectory + @"\Players\J\130\stand\1.png"));
                return;
            }
            spirit.Source = cutImage(Environment.CurrentDirectory + @"\Players\J\130\run\left.png", count * 150, 0, 150, 150);
            count = count == 11 ? 0 : count + 1;
        }

        /// <summary>
        /// 初始化矩阵
        /// </summary>
        private void InitMatrix()
        {
            //
            for (int i = 0; i < Matrix.GetUpperBound(0); i++)
            {
                for (int j = 0; j < Matrix.GetUpperBound(1); j++)
                {
                    Matrix[i, j] = 1;
                }
            }

            for (int i = 4; i < 20; i++)
            {
                Matrix[i, 4] = 0;
                rect = new Rectangle() { Width = GridSize, Height = GridSize, Fill = new SolidColorBrush(Colors.Red) };
                c.Children.Add(rect);
                Canvas.SetLeft(rect, i * GridSize);
                Canvas.SetTop(rect, 4 * GridSize);
            }

            for (int i = 4; i < 20; i++)
            {
                Matrix[i, 8] = 0;
                rect = new Rectangle() { Width = GridSize, Height = GridSize, Fill = new SolidColorBrush(Colors.Red) };
                c.Children.Add(rect);
                Canvas.SetLeft(rect, i * GridSize);
                Canvas.SetTop(rect, 8 * GridSize);
            }
        }

        Image spirit = null;
        private void InitPlayer()
        {
            spirit = new Image() { Width = 150, Height = 150 };
            c.Children.Add(spirit);
            Canvas.SetLeft(spirit,  GridSize);
            Canvas.SetTop(spirit, GridSize);
        }

        private void c_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            timer.Start();
            Point p = e.GetPosition(c);
            p.Offset(-70, -100);

            //进行坐标系缩小，以s开头表示start，后跟x或y表示坐标轴方向
            int s_x = (int)Canvas.GetLeft(spirit) / GridSize;
            int s_y = (int)Canvas.GetTop(spirit) / GridSize;
            Start = new  System.Drawing.Point(s_x, s_y);//设置起点坐标
            int e_x = (int)p.X / GridSize;
            int e_y = (int)p.Y / GridSize;
            End = new  System.Drawing.Point(e_x, e_y);

            PathFinder = new PathFinderFast(Matrix);
            PathFinder.Formula = HeuristicFormula.Manhattan;
            PathFinder.HeavyDiagonals = true;//允许对角线移动
            PathFinder.HeuristicEstimate = 0;
            path = PathFinder.FindPath(Start, End);
            //注意：查找到的点是从终点到起点！！！
        

            if (path == null)
            {
                MessageBox.Show("找不到可行之路！");
            }
            else
            {
                Point[] framePosition = new Point[path.Count];
                for (int i = path.Count - 1; i >= 0; i--)
                {
                    //从起点开始以GridSize为单位，顺序填充关键帧坐标集，并进行坐标系放大
                    framePosition[path.Count - 1 - i] = new Point(path[i].X * GridSize, path[i].Y * GridSize);
                    /*反向赋值*/
                }

                storyboard = new Storyboard();
                int cost = 100;//每移动一个方格花费100毫秒
                DoubleAnimationUsingKeyFrames dakeyX = new DoubleAnimationUsingKeyFrames() { Duration = TimeSpan.FromMilliseconds(path.Count * cost) };
                Storyboard.SetTarget(dakeyX, spirit);
                Storyboard.SetTargetProperty(dakeyX,new PropertyPath("(Canvas.Left)"));

                DoubleAnimationUsingKeyFrames dakeyY = new DoubleAnimationUsingKeyFrames() { Duration = TimeSpan.FromMilliseconds(path.Count * cost) };
                Storyboard.SetTarget(dakeyY, spirit);
                Storyboard.SetTargetProperty(dakeyY, new PropertyPath("(Canvas.Top)"));

                for (int i = 0; i < framePosition.Count(); i++)
                {
                    //加入X轴方向的匀速关键帧
                    LinearDoubleKeyFrame keyFrame = new LinearDoubleKeyFrame();
                    keyFrame.Value = i == 0 ? Canvas.GetLeft(spirit) : framePosition[i].X; //平滑衔接动画
                    keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
                    dakeyX.KeyFrames.Add(keyFrame);
                    //加入X轴方向的匀速关键帧
                    keyFrame = new LinearDoubleKeyFrame();
                    keyFrame.Value = i == 0 ? Canvas.GetTop(spirit) : framePosition[i].Y;
                    keyFrame.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(cost * i));
                    dakeyY.KeyFrames.Add(keyFrame);
                }
                storyboard.Children.Add(dakeyX);
                storyboard.Children.Add(dakeyY);

                storyboard.Begin();

                //用白色点记录移动轨迹
                for (int i = path.Count - 1; i >= 0; i--)
                {
                    rect = new Rectangle();
                    rect.Fill = new SolidColorBrush(Colors.Snow);
                    rect.Width = 5;
                    rect.Height = 5;
                    c.Children.Add(rect);
                    Canvas.SetLeft(rect, path[i].X * GridSize + 50);
                    Canvas.SetTop(rect, path[i].Y * GridSize + 100);
                }
            }
        }

        private BitmapSource cutImage(string iamgeUri, int x, int y, int w, int h)
        {
            return new CroppedBitmap(
                BitmapFrame.Create(new Uri(iamgeUri)),
                new Int32Rect(x, y, w, h));
        }
    }
}
